package servidor.tcp;



import servidor.auxiliar.GereServer;
import common.*;
import cliente.gui.Erro;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Socket;
import java.sql.*;
import servidor.auxiliar.DataCliente;


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author A8
 */
public class ConexaoServer extends Thread {

    Socket tcp_client;
    ObjectInputStream in;
    ObjectOutputStream out;
    DatagramSocket udp_client;
    DatagramPacket send;
    DatagramPacket receive;
    Connection connect = null;
    GereServer gestorServer;
    private String estado = "Desligado";

    public ConexaoServer(Socket tcp_client, Connection connect, GereServer gestorServer) {
        this.tcp_client = tcp_client;
        this.gestorServer = gestorServer;
        try {
            in = new ObjectInputStream(tcp_client.getInputStream());
            out = new ObjectOutputStream(tcp_client.getOutputStream());
            System.out.println("In e out criados com sucesso!!!");
            estado = "Ligado";
        } catch (IOException ex) {
            System.out.println("[ERRO]Erro na criacao do canal de comunicacao!\n" + ex.getMessage());
        }
    }

    synchronized public void setEstado(String estado) {
        this.estado = estado;
    }

    synchronized public String getEstado() {
        return estado;
    }

    public GereServer getGestorServer() {
        return gestorServer;
    }

    public void setGestorServer(GereServer gestorServer) {
        this.gestorServer = gestorServer;
    }

    public void run() {
        //------------------------------------------------- DATASTREAMS
        Menssagem mensagem = new Menssagem();

        while (true) {
            try {
                if (estado.equalsIgnoreCase("Off")) {
                    return;
                }
                System.out.println("[INFO]A espera de receber mensagem!!!");

                mensagem = (Menssagem) in.readObject();

                System.out.println("Recebi!!!");
                System.out.println("Mensagem:" + mensagem.getEmissor() + " - " + mensagem.getMenssagem() + " - " + mensagem.getTime());

                Menssagem resp = null;

                if (mensagem instanceof OpLogin) {
                    resp = gestorServer.doLoggin(mensagem);
                    if(resp.getMenssagem().equalsIgnoreCase("login ok"))
                        adicionaClienteLigado_TCP(mensagem.getEmissor());
                }

                if (mensagem instanceof OpRegister) {
                    resp = gestorServer.doRegister(mensagem);
                    if(resp.getMenssagem().equalsIgnoreCase("register ok"))
                        adicionaClienteLigado_TCP(mensagem.getEmissor());
                }

                if (mensagem instanceof OpFollowing) {
                    resp = gestorServer.showFollowing(mensagem);
                }

                if (mensagem instanceof OpFollowers) {
                    resp = gestorServer.showFollowers(mensagem);
                }

                if (mensagem instanceof OpSearch) {
                    resp = gestorServer.showSearch(mensagem);
                }

                if (mensagem instanceof OpFollow) {
                    resp = gestorServer.doFollow(mensagem);
                }

                if (mensagem.getMenssagem().contains("Tweet")) {
                    resp = gestorServer.doTweet(mensagem);
                }

                if (mensagem.getMenssagem().contains("Ver mensagens")) {
                    resp = gestorServer.seeTweets(mensagem);
                }

                if (mensagem.getMenssagem().contains("Detalhes")) {
                    resp = gestorServer.showDetails(mensagem);
                }

                if (mensagem.getMenssagem().contains("Minhas")) {
                    resp = gestorServer.seeMyTweets(mensagem);
                }
                
                if (mensagem.getMenssagem().contains("Loggout")) {
                    resp = gestorServer.fazLoggout(mensagem);

                }

                if (!verificaErros(resp) && resp != null) {
                    if(!resp.getMenssagem().contains("Loggout ok"))
                        enviaSms(resp);
                }
            } catch (IOException ex) {
                System.out.println("[ERRO]IO:" + ex.getMessage());
                break;
            } catch (Exception ex) {
                System.out.println("[ERRO]-CS:" + ex.getMessage());
                ex.printStackTrace();
                break;
            }
        }

    }

    public void trataErros(OpErro erro) {

        new Erro(erro.getTipo(), erro.getCausa());
    }

    public boolean verificaErros(Menssagem resp) {

        if (resp.getMenssagem().contains("ERRO")) {
            OpErro erro = (OpErro) resp;
            if (!erro.getTipo().equalsIgnoreCase("dados")) {
                System.out.println("Do tipo sistema");
                trataErros(erro);
                return true;
            }
            enviaSms(erro);
            return true;
        }
        return false;
    }

    public void enviaSms(Menssagem env) {
        try {
            out.writeObject(env);
        } catch (IOException ex) {
            System.out.println("[ERRO]:No envio de mensagem!\n" + ex.getMessage()+"\nA remover Cliente de online.");
            gestorServer.getClientes().desliga(gestorServer.getClientes().pesquisaCanal(out));
        }
    }

    public void enviaSmsFollers(Menssagem env, DataCliente cliente){
        try {

            cliente.getOut().writeObject(env);
        } catch (IOException ex) {
            System.out.println("[ERRO]:No envio de mensagem!\n" + ex.getMessage()+"\nA remover Cliente de online.");
            gestorServer.getClientes().desliga(cliente);
        }
    }

    public ObjectInputStream getObjectInput() {
        return in;
    }

    public ObjectOutputStream getObjectOutput() {
        return out;
    }

    public Socket getTcp_client() {
        return tcp_client;
    }

    public void setTcp_client(Socket tcp_client) {
        this.tcp_client = tcp_client;
    }

    public void adicionaClienteLigado_TCP(String nickname){
        DataCliente cliente = new DataCliente(out);
        cliente.setNickname(nickname);
        gestorServer.getClientes().adicionaOnline(cliente);
    }
}
